home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s2.arc / KERMCRC.MOD < prev    next >
Text File  |  1987-02-04  |  14KB  |  221 lines

  1. (*----------------------------------------------------------------------*)
  2. (*       Kermit_Chk8 --- Compute 6-bit checksum for sector in Kermit    *)
  3. (*----------------------------------------------------------------------*)
  4.  
  5. PROCEDURE Kermit_Chk8( VAR Sector        ;
  6.                            Sector_Length : INTEGER;
  7.                        VAR CheckSum      : INTEGER  );
  8.  
  9. (*----------------------------------------------------------------------*)
  10. (*                                                                      *)
  11. (*     Function: Kermit_Chk8                                            *)
  12. (*                                                                      *)
  13. (*     Purpose:  Computes 8-bit checksum for Kermit type 1 block check  *)
  14. (*                                                                      *)
  15. (*     Calling Sequence:                                                *)
  16. (*                                                                      *)
  17. (*        Checksum := Kermit_Chk8( VAR Sector ;                         *)
  18. (*                                     Sector_Length : INTEGER;         *)
  19. (*                                 VAR CheckSum      : INTEGER  );      *)
  20. (*                                                                      *)
  21. (*           Sector        --- data for which to compute checksum       *)
  22. (*           Sector_Length --- length of Sector in bytes                *)
  23. (*           Checksum      --- computed checksum                        *)
  24. (*                                                                      *)
  25. (*     Calls:    None                                                   *)
  26. (*                                                                      *)
  27. (*     Remarks:  In Pascal one could write the body of this procedure   *)
  28. (*               as follows:                                            *)
  29. (*                                                                      *)
  30. (*                  CheckSum := 0;                                      *)
  31. (*                                                                      *)
  32. (*                  FOR I := 1 TO Sector_Length DO                      *)
  33. (*                     CheckSum := ( CheckSum + Sector[I] ) AND 255;    *)
  34. (*                                                                      *)
  35. (*----------------------------------------------------------------------*)
  36.  
  37. BEGIN (* Kermit_Chk8 *)
  38.  
  39. INLINE(
  40.   $1E                    {          PUSH   DS                       ;Save DS}
  41.                          {;}
  42.   /$31/$D2               {          XOR    DX,DX                    ;Accumulates checksum}
  43.   /$31/$C0               {          XOR    AX,AX                    ;Clear byte holder}
  44.   /$8B/$8E/>SECTOR_LENGTH{          MOV    CX,[BP+>Sector_Length]   ;Get sector length}
  45.   /$C5/$B6/>SECTOR       {          LDS    SI,[BP+>Sector]          ;Get sector address}
  46.   /$BB/$FF/$00           {          MOV    BX,255                   ;1 byte checksum}
  47.   /$FC                   {          CLD                             ;March forward}
  48.                          {;}
  49.   /$AC                   {Chk8:     LODSB                           ;Get next byte in sector}
  50.   /$01/$C2               {          ADD    DX,AX                    ;Add next byte to checksum}
  51.   /$21/$DA               {          AND    DX,BX                    ;Mask out high-order checksum bits}
  52.   /$E2/$F9               {          LOOP   Chk8}
  53.                          {;}
  54.   /$C4/$BE/>CHECKSUM     {          LES    DI,[BP+>CheckSum]        ;Get result address}
  55.   /$26/$89/$15           {      ES: MOV    [DI],DX                  ;Move checksum to function result}
  56.                          {;}
  57.   /$1F                   {          POP    DS                       ;Restore DS}
  58. );
  59.  
  60. END   (* Kermit_Chk8 *);
  61.  
  62. (*----------------------------------------------------------------------*)
  63. (*       Kermit_Chk12 --- Compute 12-bit checksum for sector in Kermit  *)
  64. (*----------------------------------------------------------------------*)
  65.  
  66. PROCEDURE Kermit_Chk12( VAR Sector        ;
  67.                             Sector_Length : INTEGER;
  68.                         VAR CheckSum      : INTEGER  );
  69.  
  70. (*----------------------------------------------------------------------*)
  71. (*                                                                      *)
  72. (*     Procedure: Kermit_Chk12                                          *)
  73. (*                                                                      *)
  74. (*     Purpose:   Computes 12-bit checksum for Kermit type2 block check *)
  75. (*                                                                      *)
  76. (*     Calling Sequence:                                                *)
  77. (*                                                                      *)
  78. (*        Checksum := Kermit_Chk12( VAR Sector ;                        *)
  79. (*                                      Sector_Length : INTEGER;        *)
  80. (*                                  VAR CheckSum      : INTEGER  );     *)
  81. (*                                                                      *)
  82. (*           Sector        --- data for which to compute checksum       *)
  83. (*           Sector_Length --- length of Sector in bytes                *)
  84. (*           Checksum      --- computed checksum                        *)
  85. (*                                                                      *)
  86. (*     Calls:    None                                                   *)
  87. (*                                                                      *)
  88. (*     Remarks:  In Pascal one could write the body of this procedure   *)
  89. (*               as follows:                                            *)
  90. (*                                                                      *)
  91. (*                  CheckSum := 0;                                      *)
  92. (*                                                                      *)
  93. (*                  FOR I := 1 TO Sector_Length DO                      *)
  94. (*                     CheckSum := ( CheckSum + Sector[I] ) AND 4095;   *)
  95. (*                                                                      *)
  96. (*                  Kermit_Chk12 := CheckSum;                           *)
  97. (*                                                                      *)
  98. (*----------------------------------------------------------------------*)
  99.  
  100. BEGIN (* Kermit_Chk12 *)
  101.  
  102. INLINE(
  103.   $1E                    {          PUSH   DS                       ;Save DS}
  104.                          {;}
  105.   /$31/$C0               {          XOR    AX,AX                    ;Gets bytes in sector}
  106.   /$31/$D2               {          XOR    DX,DX                    ;Accumulates checksum}
  107.   /$8B/$8E/>SECTOR_LENGTH{          MOV    CX,[BP+>Sector_Length]   ;Get sector length}
  108.   /$C5/$B6/>SECTOR       {          LDS    SI,[BP+>Sector]          ;Get sector address}
  109.   /$BB/$FF/$0F           {          MOV    BX,4095                  ;1 byte checksum}
  110.   /$FC                   {          CLD                             ;March forward}
  111.                          {;}
  112.   /$AC                   {Chk12:    LODSB                           ;Get next byte in sector}
  113.   /$01/$C2               {          ADD    DX,AX                    ;Add next byte to checksum}
  114.   /$21/$DA               {          AND    DX,BX                    ;Mask out high-order checksum bits}
  115.   /$E2/$F9               {          LOOP   Chk12}
  116.                          {;}
  117.   /$C4/$BE/>CHECKSUM     {          LES    DI,[BP+>CheckSum]        ;Get result address}
  118.   /$26/$89/$15           {      ES: MOV    [DI],DX                  ;Move answer to function result}
  119.                          {;}
  120.   /$1F                   {          POP    DS                       ;Restore DS}
  121. );
  122.  
  123. END   (* Kermit_Chk12 *);
  124.  
  125. (*----------------------------------------------------------------------*)
  126. (*       Kermit_CRC --- Compute cyclic redundancy check for Kermit      *)
  127. (*----------------------------------------------------------------------*)
  128.  
  129. PROCEDURE Kermit_CRC( VAR Sector        ;
  130.                           Sector_Length : INTEGER;
  131.                       VAR CRC           : INTEGER  );
  132.  
  133. (*----------------------------------------------------------------------*)
  134. (*                                                                      *)
  135. (*     Procedure: Kermit_CRC                                            *)
  136. (*                                                                      *)
  137. (*     Purpose:   Computes 16-bit CRC for Kermit type 3 block check     *)
  138. (*                                                                      *)
  139. (*     Calling Sequence:                                                *)
  140. (*                                                                      *)
  141. (*        Kermit_CRC( VAR Sector        ;                               *)
  142. (*                        Sector_Length : INTEGER;                      *)
  143. (*                    VAR CRC           : INTEGER  );                   *)
  144. (*                                                                      *)
  145. (*           Sector        --- data for which to compute CRC            *)
  146. (*           Sector_Length --- length of Sector in bytes                *)
  147. (*           CRC           --- computed CRC                             *)
  148. (*                                                                      *)
  149. (*     Calls:    None                                                   *)
  150. (*                                                                      *)
  151. (*     Remarks:  In Pascal one could write the body of this procedure   *)
  152. (*               as follows:                                            *)
  153. (*                                                                      *)
  154. (*                  Crc := 0;                                           *)
  155. (*                                                                      *)
  156. (*                  FOR I := 1 TO Sector_Length DO                      *)
  157. (*                     BEGIN                                            *)
  158. (*                        C     := Sector[I] XOR LO( Crc );             *)
  159. (*                        CSave := ( C AND $F0 ) SHR 4;                 *)
  160. (*                        C     := C AND $0F;                           *)
  161. (*                        Crc   := ( Crc SHR 8 ) XOR                    *)
  162. (*                                 ( CrcTab[ CSave ] XOR CrcTab2[ C ] );*)
  163. (*                     END;                                             *)
  164. (*                                                                      *)
  165. (*----------------------------------------------------------------------*)
  166.  
  167. CONST
  168.    CrcTab:  ARRAY[0..15] OF INTEGER
  169.             = ( $0000, $1081, $2102, $3183, $4204, $5285, $6306, $7387,
  170.                 $8408, $9489, $A50A, $B58B, $C60C, $D68D, $E70E, $F78F  );
  171.  
  172.    CrcTab2: ARRAY[0..15] OF INTEGER
  173.             = ( $0000, $1189, $2312, $329B, $4624, $57AD, $6536, $74BF,
  174.                 $8C48, $9DC1, $AF5A, $BED3, $CA6C, $DBE5, $E97E, $F8F7  );
  175.  
  176. BEGIN (* Kermit_CRC *)
  177.  
  178. INLINE(
  179.   $1E                    {          PUSH   DS                       ;Save DS}
  180.                          {;}
  181.   /$31/$D2               {          XOR    DX,DX                    ;Accumulates CRC}
  182.   /$8B/$8E/>SECTOR_LENGTH{          MOV    CX,[BP+>Sector_Length]   ;Get sector length}
  183.   /$C5/$B6/>SECTOR       {          LDS    SI,[BP+>Sector]          ;Get sector address}
  184.   /$FC                   {          CLD                             ;March forward}
  185.                          {;}
  186.   /$51                   {Crc1:     PUSH   CX                       ;Save loop counter}
  187.                          {;}
  188.   /$AC                   {          LODSB                           ;Get next byte in sector}
  189.                          {;}
  190.   /$30/$D0               {          XOR    AL,DL                    ;C = B XOR LO( Crc )}
  191.   /$88/$C3               {          MOV    BL,AL                    ;CSave := C}
  192.   /$81/$E3/$F0/$00       {          AND    BX,$F0                   ;Csave := ( CSAve AND $F0 )}
  193.   /$D0/$EB               {          SHR    BL,1                     ;  ... SHR 1}
  194.   /$D0/$EB               {          SHR    BL,1                     ;  ... SHR 2}
  195.   /$D0/$EB               {          SHR    BL,1                     ;  ... SHR 3}
  196.   /$25/$0F/$00           {          AND    AX,$0F                   ;C     := C AND $0F}
  197.   /$D0/$E0               {          SHL    AL,1}
  198.   /$B1/$08               {          MOV    CL,8}
  199.   /$D3/$EA               {          SHR    DX,CL                    ;CRC := ( CRC SHR 8 ) ...}
  200.   /$8D/$3E/>CRCTAB       {          LEA    DI,[>CrcTab]}
  201.   /$01/$DF               {          ADD    DI,BX}
  202.   /$2E/$8B/$1D           {      CS: MOV    BX,[DI]                  ;CrcTab[ CSave ]}
  203.   /$8D/$3E/>CRCTAB2      {          LEA    DI,[>CrcTab2]}
  204.   /$01/$C7               {          ADD    DI,AX}
  205.   /$2E/$8B/$05           {      CS: MOV    AX,[DI]                  ;CrcTab2[ C ]}
  206.   /$31/$D8               {          XOR    AX,BX}
  207.   /$31/$C2               {          XOR    DX,AX}
  208.                          {;}
  209.   /$59                   {          POP    CX                       ;Restore loop counter}
  210.   /$E2/$CE               {          LOOP   Crc1                     ;Go back if sector not done yet}
  211.                          {;}
  212.   /$C4/$BE/>CRC          {          LES    DI,[BP+>Crc]             ;Pick up return address}
  213.   /$26/$89/$15           {      ES: MOV    [DI],DX                  ;Store result}
  214.                          {;}
  215.   /$1F                   {          POP    DS                       ;Restore DS}
  216.                          {;}
  217. );
  218.  
  219. END   (* Kermit_CRC *);
  220.  
  221.